package com.base.invoke.okhttp.handle;

import java.io.IOException;

import com.base.invoke.okhttp.callback.Callback;
import com.base.invoke.okhttp.request.OkHttpReq;
import com.base.invoke.okhttp.response.Response;
import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;

/**
 * @desc 发送请求类，该类用来发起OkHttp的网络请求（同步、异步），
 * 并将请求结果返回给调用者，该类初始化系统拦截器，并启动拦截器链
 * @author coolpig
 * @date 2019-08-28
 */
public class RequestCallback {
	//
	private OkHttpClient okHttpClient;
	private OkHttpReq okHttpReq;
	private Request req;
	private Call call;
	//
	public RequestCallback(OkHttpReq request, OkHttpClient okHttpClient) {
		this.okHttpReq = request;
		this.okHttpClient=okHttpClient;
	}
	
	public Call buildCall(Callback callback) {
		req = createRequest(callback);
		call = okHttpClient.newCall(req);
		return call;
	}

	private Request createRequest(Callback callback) {
		return okHttpReq.createRequest(callback);
	}
	
	public Response execute() throws Exception{

		buildCall(null);
		try {
			Response rsp=new Response(call.execute());
			if(rsp.isSuccessful()){
				OkHttpClientStat.doReqSuccess();
			}else{
				OkHttpClientStat.doRequstFail(call.request().url().toString(),null);
			}
			return rsp;
		} catch (Exception ex) {
			OkHttpClientStat.doRequstFail(call.request().url().toString(), ex);
			throw ex;
		}
	}

	public void executeAsync(Callback callback) {
		buildCall(callback);
		execute(this,callback);
	}

	private void execute(final RequestCallback rcb, Callback cb) {
		final Callback fcb = cb;
		final int id = rcb.getOkHttpRequest().getId();
		rcb.getCall().enqueue(new okhttp3.Callback() {
			@Override
			public void onFailure(Call c, final IOException ex) {
				OkHttpClientStat.doRequstFail(c.request().url().toString(),ex);
				if(fcb != null)fcb.doFailure(c, ex, id);
			}

			@Override
			public void onResponse(final Call c, final okhttp3.Response response) {
				OkHttpClientStat.doReqSuccess();
				if(fcb != null)fcb.doResponse(c, new Response(response), id);
			}
		});
	}
	
	public Call getCall() {
		return call;
	}

	public Request getRequest() {
		return req;
	}

	public OkHttpReq getOkHttpRequest() {
		return okHttpReq;
	}

	public void cancel() {
		if (call != null) {
			call.cancel();
		}
	}
}
